// taskQueue.c
#include "taskQueue.h"

void _taskQueue_init(_taskQueue_t* q){
    bzero(q, sizeof(_taskQueue_t));
}

int _taskQueue_enque(_taskQueue_t* q, task_t* task){
    _taskNode_t* node = (_taskNode_t*)calloc(1, sizeof(_taskNode_t));
    ERROR_CHECK(node, NULL, "_taskQueue_enque calloc");
    node->task = task;

    if(_taskQueue_is_empty(q)){
        q->front = node;
    }else{
        q->rear->next = node;
    }
    q->rear = node;
    ++q->size;
    return 0;
}

int _taskQueue_deque(_taskQueue_t* q){
    if(_taskQueue_is_empty(q)){
        fprintf(stderr, "deque in empty taskQueue\n");
        return -1;
    }

    _taskNode_t* tmp = q->front;
    q->front = q->front->next;
    if(q->size == 1){
        q->rear = NULL;
    }
    --q->size;

    free(tmp);
    tmp = NULL;
    return 0;
}

bool _taskQueue_is_empty(_taskQueue_t* q){
    return q->size == 0;
}

task_t* _taskQueue_front(_taskQueue_t* q){
    if(_taskQueue_is_empty(q)){
        fprintf(stderr, "get front from empty taskQueue\n");
        return NULL;
    }
    return q->front->task;
}

// unit test
/* int main() { */
/*     _taskQueue_t queue; */
    
/*     // 测试1：初始化队列后队列应为空 */
/*     _taskQueue_init(&queue); */
/*     if(_taskQueue_is_empty(&queue)) { */
/*         printf("测试1：初始化后队列为空\n"); */
/*     } else { */
/*         printf("测试1失败：初始化后队列不为空\n"); */
/*     } */
    
/*     // 测试2：入队一个元素 */
/*     _taskQueue_enque(&queue, 100); */
/*     if(!_taskQueue_is_empty(&queue)) { */
/*         int front = _taskQueue_front(&queue); */
/*         printf("测试2：入队100后，队头元素为 %d\n", front); */
/*     } else { */
/*         printf("测试2失败：入队后队列仍为空\n"); */
/*     } */
    
/*     // 测试3：继续入队两个元素，队头仍应为100 */
/*     _taskQueue_enque(&queue, 200); */
/*     _taskQueue_enque(&queue, 300); */
/*     int front = _taskQueue_front(&queue); */
/*     printf("测试3：再入队200和300后，队头元素仍应为100，实际为 %d\n", front); */
    
/*     // 测试4：出队一个元素后，队头应变为200 */
/*     _taskQueue_deque(&queue); */
/*     front = _taskQueue_front(&queue); */
/*     printf("测试4：出队一个元素后，队头元素应为200，实际为 %d\n", front); */
    
/*     // 测试5：出队剩余元素后队列为空 */
/*     _taskQueue_deque(&queue); */
/*     _taskQueue_deque(&queue); */
/*     if(_taskQueue_is_empty(&queue)) { */
/*         printf("测试5：出队所有元素后队列为空\n"); */
/*     } else { */
/*         printf("测试5失败：出队后队列不为空\n"); */
/*     } */
    
/*     // 测试6：对空队列进行出队操作，返回错误 */
/*     int ret = _taskQueue_deque(&queue); */
/*     if(ret == -1) { */
/*         printf("测试6：空队列出队操作正确返回错误\n"); */
/*     } else { */
/*         printf("测试6失败：空队列出队操作未返回错误\n"); */
/*     } */
    
/*     // 测试7：对空队列进行获取队头操作，返回错误 */
/*     int front_val = _taskQueue_front(&queue); */
/*     if(front_val == -1) { */
/*         printf("测试7：空队列获取队头操作正确返回错误\n"); */
/*     } else { */
/*         printf("测试7失败：空队列获取队头操作未返回错误\n"); */
/*     } */
    
/*     return 0; */
/* } */
